package com.iot.hmi.protocol;

import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
import com.iot.hmi.entity.IotDevice;
import com.iot.hmi.entity.IotDeviceItem;

public class SiemensProtocolServiceImpl extends AbstractProtocol {
    private S7PLC plc = null;

    public SiemensProtocolServiceImpl(IotDevice device) {
        super(device);
    }

    @Override
    public void connect() {
        plc = new S7PLC(
                this.getPlcType(deviceInfo().getProtocolType()),
                deviceInfo().getProtocolHost(),
                deviceInfo().getProtocolPort()
        );
    }

    private EPlcType getPlcType(String protocolType) {
        switch (protocolType) {
            case "S7-1200":
                return EPlcType.S1200;
            case "S7-1500":
                return EPlcType.S1500;
            case "S7-200":
                return EPlcType.S200;
            case "S7-200_SMART":
                return EPlcType.S200_SMART;
            case "S7-300":
                return EPlcType.S300;
            case "S7-400":
                return EPlcType.S400;
            default:
                return null;
        }
    }

    @Override
    public String read(IotDeviceItem item) {
        if (!isConnected()) {
            return null;
        }
        switch (item.getItemType()) {
            case "float32":
                return Float.toString(plc.readFloat32(item.getItemAddress()));
            case "float64":
                return Double.toString(plc.readFloat64(item.getItemAddress()));
            case "string":
                return plc.readString(item.getItemAddress());
            case "byte":
                return Byte.toString(plc.readByte(item.getItemAddress()));
            case "boolean":
                return Boolean.toString(plc.readBoolean(item.getItemAddress()));
            case "uint16":
            case "int16":
                return Short.toString(plc.readInt16(item.getItemAddress()));
            case "int32":
            case "uint32":
                return Integer.toString(plc.readInt32(item.getItemAddress()));
            default:
                return null;
        }
    }

    @Override
    public void disConnect() {
        if (this.plc == null) {
            return;
        }
        this.plc.close();
        this.plc = null;
    }

    @Override
    public boolean isConnected() {
        return this.plc != null;
    }
}
